#ifndef WIDGETS_H_
#define WIDGETS_H_

#include "QCore.h"
#include "QEvent.h"
#include "QGui.h"
using namespace std;

class QLayout;
class QWidget : public QObject
{
public:    
    struct no_create_widget {
    };

    explicit QWidget(QWidget *parent = NULL);
    QWidget(widget_t *wid, QWidget *parent);
    QWidget(no_create_widget no, QWidget *parent);
    virtual ~QWidget();
    
    DECLARETION_META(QWidget)

    widget_t *wid();    
    canvas_t *canvas();

    QWidget *parentWidget();
    void setParent(QWidget *widget);
    
    QFont font();
    void setFont(const QFont &ft);

    void setEnabled(bool flag); 
    bool isEnabled();

    QPoint mapToGlobal(QPoint pt);
    QPoint mapFromGlobal(QPoint pt);
    void setStyleSheet(const QString &styleSheet);

    void setLayout(QLayout *layout);    

    void move(int x, int y);        
    void resize(int w, int h);
    void resize(QSize size);    
    
    void setFixedWidth(int width);
    void setFixedHeight(int width);
    void setFixedSize(int x, int y);
    void setFixedSize(QSize sz);

    void setMinimumWidth(int width);
    void setMinimumHeight(int height);
    void setMinimumSize(int x, int y);
    void setMinimumSize(QSize sz);

    void setMaximumWidth(int width);
    void setMaximumHeight(int height);
    void setMaximumSize(int x, int y);
    void setMaximumSize(QSize sz);

    void setGeometry(QRect rc);
    void setGeometry(int x,int y,int w,int h); 
    QRect geometry();    
    QRect rect();    
    QSize size();
    int x();
    int y();
    int width();
    int height();

    void setVisible(bool visible);
    void show();
    void hide();

    void update();

    int onPaint(canvas_t* e);
    int onEvent(event_t* e);

    void dumpWidgetTree();

protected:                    
    virtual void paintEvent(QPaintEvent *event);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);    
    
    canvas_t *m_canvas;
    widget_t *m_wid;

private:
    void dump(QWidget *widget, int level);
    void dump(widget_t *wid, int level);
};

class Window : public QWidget
{
public:
    Window();

    DECLARETION_META(Window)
};    


class QIcon;
class QButtonGroup;

class QAbstractButton : public QWidget
{
public:
    QAbstractButton(QWidget *parent);

    DECLARETION_META(QAbstractButton)

    QButtonGroup *group() const;    

    void setCheckable(bool flag);
    void setChecked(bool flag);
    bool isChecked();

    void setText(QString text);
    void setIcon(const QIcon &icon);
    void setIconSize(const QSize &icon_size);

protected:
    friend QButtonGroup;

    QButtonGroup *m_buttonGroup;
};

class QPushButton : public QAbstractButton
{
public:    
    QPushButton(QWidget *parent);    
    QPushButton(const QString &text, QWidget *parent);
    virtual ~QPushButton();
       
    DECLARETION_META(QPushButton)
protected:
};

class QSwitchButton : public QWidget
{
public:
    QSwitchButton(QWidget *parent);

    DECLARETION_META(QSwitchButton)
};

class QRadioButton : public QAbstractButton
{
public:
    QRadioButton(QWidget *parent);
    QRadioButton(const QString &text, QWidget *parent);

    DECLARETION_META(QRadioButton)
};

class QButtonGroup : public QObject
{
public:
    QButtonGroup(QObject *parent);

    DECLARETION_META(QButtonGroup)

    void addButton(QAbstractButton *button,int id = -1);

protected:
    QVector<QAbstractButton *> m_buttons;
};

class QLabel : public QWidget
{
public:    
    QLabel(QString label,QWidget *parent = NULL);
    QLabel(QWidget *parent = NULL);
    virtual ~QLabel();

    DECLARETION_META(QLabel)

    QString text();
    void setText(QString text);
    void setAlignment(int align);

protected:

};

class QStackedWidget : public QWidget
{
public:    
    QStackedWidget(QWidget *parent);

    DECLARETION_META(QStackedWidget)

    void addWidget(QWidget *widget);
    void setCurrentIndex(int index);
    int currentIndex();

protected:
    int m_currentIndex;
    QVector<QWidget*> m_widgets;    
};

class QListWidgetItem
{
public:    
    QListWidgetItem();

    QWidget *widget;
};

class QListWidget : public QWidget
{
public:
    QListWidget(QWidget *parent);
    ~QListWidget();

    DECLARETION_META(QListWidget)

    void addItem(const QString &label);
    void addItem(QListWidgetItem *item);
    QListWidgetItem *takeItem(int row);
        
    void setItemWidget(QListWidgetItem *item, QWidget *widget);
    void addItemWidget(QWidget *widget);

    int count();

protected:
    QVector<QListWidgetItem*> m_items;
    QWidget *m_view;    
};

class QScrollArea : public QWidget
{
public:
    QScrollArea(QWidget *parent);
    ~QScrollArea();

    DECLARETION_META(QScrollArea)

    void setWidget(QWidget *widget);
    void setWidgetResizable(bool flag);

protected:
    QWidget *m_scrollView;
    QWidget *m_viewport;
};

class QLayoutItem
{
public:
    QLayoutItem();

    QWidget *widget;
    int row;
    int col;
    int align;
};

class QLayout
{
public:
    QLayout(QWidget *parent);
    virtual ~QLayout();

    void update();
    void setContentsMargins(int left, int top, int right, int bottom);
    void setMargin(int size);
    void setSpacing(int space);

protected:    
    virtual void doLayout() = 0;    
    void addLayoutItem(const QLayoutItem &item);

    QWidget *m_widget;
    QVector<QLayoutItem> m_items;
    int m_left;
    int m_top;
    int m_right;
    int m_bottom;
    int m_spacing;
};

class QBoxLayout: public QLayout
{
public:
    QBoxLayout(QWidget *parent);

    void addWidget(QWidget *widget,int stretch = 0,int align = 0);

protected:
    int m_dir;
};

class QHBoxLayout: public QBoxLayout
{
public:
    QHBoxLayout(QWidget *parent);

protected:
    virtual void doLayout();
};

class QVBoxLayout: public QBoxLayout
{
public:
    QVBoxLayout(QWidget *parent);

protected:
    virtual void doLayout();
};

class QGridLayout : public QBoxLayout
{
public:
    QGridLayout(QWidget *parent);

    void addWidget(QWidget *widget, int row, int column,int align = 0);

protected:
    virtual void doLayout();
};

void widget_init();


#endif